﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Ids.OrganogramDesigner;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using System.Collections;
using System.Configuration;
using System.Net;
using System.ServiceModel.Description;

namespace BusinessUnitOrgChart
{
    public partial class Ribbon1
    {
        private OrganizationServiceProxy _serviceProxy;
        private IOrganizationService _service;
        UriBuilder organizationUri;
        Microsoft.Office.Interop.Visio.Page active_page;
        Microsoft.Office.Interop.Visio.Document doc;

        private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
        {
         
        }

        private void btnGenerateDiagram_Click(object sender, RibbonControlEventArgs e)
        {
            ConnectToCRM();
            EntityCollection businessUnitsCollection = GetBusinessUnits();
            DrawObjects(businessUnitsCollection);
        }

        private void ConnectToCRM()
        {
            try
            {
                if (!cbHTTPS.Checked)
                {
                    if (ebPort.Text.Length > 0) organizationUri = new UriBuilder("http", ebCRMServer.Text, Int32.Parse(ebPort.Text), ebOrg.Text + "/XRMServices/2011/Organization.svc");
                    else organizationUri = new UriBuilder("http", ebCRMServer.Text, 80, ebOrg.Text + "/XRMServices/2011/Organization.svc");
                }
                else
                {
                    
                    organizationUri = new UriBuilder("https", ebCRMServer.Text, 443, ebOrg.Text + "/XRMServices/2011/Organization.svc");
                }
                Uri homeRealmUri = null;
                ClientCredentials credentials = new ClientCredentials();
                // set default credentials for OrganizationService
                credentials.Windows.ClientCredential = new NetworkCredential(ebUsername.Text, ebPassword.Text, ebDomain.Text);

                //Create serviceProxy
                _serviceProxy = new OrganizationServiceProxy(organizationUri.Uri, homeRealmUri, credentials, null);

                _service = (IOrganizationService)_serviceProxy; 
            }
            catch (Exception e)
            {
                
            }
        }

        public EntityCollection GetBusinessUnits()
        {
            // Search for contact using Skype username          
            string fetchXML = @"<fetch distinct='false' mapping='logical' aggregate='false'>
                    <entity name='businessunit'>
                        <attribute name='businessunitid'/>
                        <attribute name='name'/>
                        <attribute name='parentbusinessunitid'/>
		                <filter type='and'>
                            <condition attribute='isdisabled' operator='eq' value='0'/>
                        </filter>
                    </entity>
                </fetch>";

            // Fetch the results.
            RetrieveMultipleRequest fetchRequest1 = new RetrieveMultipleRequest
            {
                Query = new FetchExpression(fetchXML)
            };


            EntityCollection e = ((RetrieveMultipleResponse)_service.Execute(fetchRequest1)).EntityCollection;

            return e;
        }

        private void DrawObjects(EntityCollection businessUnits)
        {
            int level = 1;
            int root_bu_id = 0;
            List<Box> boxes = new List<Box>();
            int id = 1;
            ArrayList businessUnitObjects = new ArrayList();


            // Add all business units to ArrayList
            foreach (Entity businessUnit in businessUnits.Entities)
            {
                string name= businessUnit["name"].ToString();
                string parent_name;

                if (businessUnit.Attributes.Contains("parentbusinessunitid"))
                {
                    EntityReference parent = (EntityReference)businessUnit["parentbusinessunitid"];
                    parent_name = parent.Name;
                    BusinessUnit bu = new BusinessUnit(id, name, parent_name);
                    
                    businessUnitObjects.Add(bu);
                }
                else
                {
                    BusinessUnit bu = new BusinessUnit(id, name);
                    root_bu_id = id;
                    businessUnitObjects.Add(bu);
                }

                id++;

            }
            
            RecursionForLevels((BusinessUnit) businessUnitObjects[root_bu_id-1], businessUnitObjects,0 );

            businessUnitObjects.Sort(new Comparer());

            int counter = 0;
            
            foreach (BusinessUnit bu in businessUnitObjects)
            {
                if (bu.parentid != 0) boxes.Add(new Box(bu.id.ToString(), bu.name, bu.parentid.ToString(), bu.level));
                else
                {
                    boxes.Add(new Box(bu.id.ToString(), bu.name));
                    boxes[0].Type = BoxTypes.Executive;
                    boxes[0].BackColor = System.Drawing.Color.Gold;                    
                    boxes[0].Parent = null;
                }

                switch (bu.level)
                {
                    case 1:
                        boxes[counter].BackColor = System.Drawing.Color.LightSteelBlue;
                        break;
                    case 2:
                        boxes[counter].BackColor = System.Drawing.Color.LightGreen;
                        break;
                    case 3:
                        boxes[counter].BackColor = System.Drawing.Color.Orange;
                        break;
                    case 4:
                        boxes[counter].BackColor = System.Drawing.Color.Wheat;
                        break;
                    case 5:
                        boxes[counter].BackColor = System.Drawing.Color.Tomato;
                        break;
                    case 6:
                        boxes[counter].BackColor = System.Drawing.Color.Lime;
                        break;
                    case 7:
                        boxes[counter].BackColor = System.Drawing.Color.Magenta;
                        break;
                    case 8:
                        boxes[counter].BackColor = System.Drawing.Color.Gray;
                        break;
                }
                counter++;
            }

            Ids.OrganogramDesigner.Designer designer = new Designer();
            designer.Boxes = boxes;

            active_page = Globals.ThisAddIn.Application.ActivePage;
            doc = Globals.ThisAddIn.Application.ActiveDocument;   

            designer.GenerateDiagram(active_page, doc);

            //List<Box> boxes = new List<Box>();

            //boxes.Add(new Box("1", "General Manager"));

            //boxes[0].Type = BoxTypes.Executive;

            //boxes.Add(new Box("2", "Research & Development", "1", 1));
            //boxes.Add(new Box("3", "Customer Support", "1", 1));
            //boxes.Add(new Box("4", "Sales", "1", 1));
            //boxes.Add(new Box("5", "Marketing", "1", 1));
            //boxes.Add(new Box("6", "Accounting", "1", 1));

            //boxes[1].Type = BoxTypes.Manager;
            //boxes[1].ForeColor = Colors.Red;

            //boxes[2].BackColor = System.Drawing.Color.LightGreen;

            //boxes.Add(new Box("9", "Project Management", "2", 2));
            //boxes.Add(new Box("10", "Quality Assurance", "2", 2));
            //boxes.Add(new Box("11", "System Analyst", "2", 2));
            //boxes.Add(new Box("12", "Development", "2", 2));

            //Ids.OrganogramDesigner.Designer designer = new Designer();
            //designer.Boxes = boxes;

            //designer.GenerateDiagram(active_page, doc);
        }

        public void RecursionForLevels(BusinessUnit parent, ArrayList businessUnitsObjects,int level)
        {
            foreach (BusinessUnit bu in businessUnitsObjects)
            {
                if (bu.parentname == parent.name)
                {
                    bu.parentid = parent.id;
                    bu.level = level + 1;
                    RecursionForLevels(bu, businessUnitsObjects, level + 1);
                }


            }

        }

        private void btnSaveConnectionData_Click(object sender, RibbonControlEventArgs e)
        {

        }
    }
}
